import socket
import sys
import time


MAX_REQUESTS_PER_SECOND = 10
REQUEST_INTERVAL = 1 / MAX_REQUESTS_PER_SECOND

def send_requests(server_host, server_port, request_file):
    last_request_time = 0
    try:
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client_socket.settimeout(10)
        client_socket.connect((server_host, server_port))
        print(f"Successfully connected to server {server_host}:{server_port}")

        with open(request_file, 'r') as file:
            for line in file:
                line = line.strip()
                if not line:
                    continue


                current_time = time.time()
                if current_time - last_request_time < REQUEST_INTERVAL:
                    time.sleep(REQUEST_INTERVAL - (current_time - last_request_time))
                last_request_time = time.time()

                command = line.split(' ')[0]
                key = line.split(' ')[1]
                value = ' '.join(line.split(' ')[2:]) if command == 'PUT' else ''
                message = f"{str(len(line) + 3).zfill(3)}{command}{key} {value}"

                try:
                    client_socket.send(message.encode('utf - 8'))
                    try:
                        response = client_socket.recv(1024).decode('utf - 8')
                        print(f"Request: {line}, Response: {response}")
                    except socket.timeout:
                        print(f"Request {line} timed out, no response received from the server. Trying to resend...")
                        client_socket.send(message.encode('utf - 8'))  # Try to resend
                        response = client_socket.recv(1024).decode('utf - 8')
                        print(f"After resending, Request: {line}, Response: {response}")
                except socket.error as e:
                    print(f"A socket error occurred while sending request {line}: {e}. Closing the connection and trying to reconnect...")
                    client_socket.close()
                    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    client_socket.settimeout(10)
                    client_socket.connect((server_host, server_port))

        client_socket.close()

    except FileNotFoundError:
        print(f"Error: Request file {request_file} not found")
    except ConnectionRefusedError:
        print(f"Error: Unable to connect to server {server_host}:{server_port}")
    except Exception as e:
        print(f"An unknown error occurred: {e}")


if __name__ == "__main__":
    if len(sys.argv) != 4:
        print("Usage: python client.py <server_host> <server_port> <request_file>")
        sys.exit(1)
    server_host = sys.argv[1]
    server_port = int(sys.argv[2])
    request_file = sys.argv[3]
    send_requests(server_host, server_port, request_file)